package cn.cachalot.oj.service.impl;

import cn.cachalot.oj.controller.param.AddQuestionParam;
import cn.cachalot.oj.controller.param.AddTestCaseParam;
import cn.cachalot.oj.controller.param.UpdateQuestionParam;
import cn.cachalot.oj.controller.param.UpdateTestcaseParam;
import cn.cachalot.oj.controller.res.*;
import cn.cachalot.oj.entity.*;
import cn.cachalot.oj.mapper.*;
import cn.cachalot.oj.service.ProblemService;
import cn.cachalot.oj.util.BaseContext;
import cn.cachalot.oj.util.R;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> implements ProblemService {
    @Resource
    ProblemMapper problemMapper;
    @Resource
    ProblemCheckMapper problemCheckMapper;
    @Resource
    ProblemDetailMapper problemDetailMapper;
    @Resource
    SubmitMapper submitMapper;
    @Resource
    SolutionMapper solutionMapper;
    @Resource
    UserMapper userMapper;

    @Override
    public List<QuestionInfoRes> getQuestionInfoResList(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        Long currentId = BaseContext.getId();
        List<Problem> problemList = problemMapper.getAll();
        List<QuestionInfoRes> resList = problemList.stream().map(item -> {
            QuestionInfoRes questionInfoRes = new QuestionInfoRes();
            BeanUtils.copyProperties(item, questionInfoRes);
            Integer count = problemMapper.getResolvedCountByProblemIdAndUserId(item.getId(), currentId);
            Double resolvedCount = problemMapper.getResolvedCountByProblemId(item.getId());
            Double submitCount = problemMapper.getSubmitCountByProblemId(item.getId());
            Double passRate = resolvedCount / submitCount;
            questionInfoRes.setPassRate(passRate);
            questionInfoRes.setIsResolved(count > 0);
            return questionInfoRes;
        }).collect(Collectors.toList());
        return resList;
    }

    @Override
    public QuestionDetailInfoRes getQuestionDetailInfoResByquestionId(Long questionId) {
        if (questionId == null) {
            return null;
        }
        Problem problem = problemMapper.getProblemByProblemId(questionId);
        ProblemDetail problemDetail = problemMapper.getProblemDetailByProblemId(questionId);
        if (problemDetail == null || problem == null) {
            return null;
        }
        QuestionDetailInfoRes questionDetailInfoRes = new QuestionDetailInfoRes();
        BeanUtils.copyProperties(problem, questionDetailInfoRes);
        BeanUtils.copyProperties(problemDetail, questionDetailInfoRes);
        Integer count = problemMapper.getResolvedCountByProblemIdAndUserId(questionId, BaseContext.getId());
        Double resolvedCount = problemMapper.getResolvedCountByProblemId(questionId);
        Double submitCount = problemMapper.getSubmitCountByProblemId(questionId);
        Double passRate = resolvedCount / submitCount;
        questionDetailInfoRes.setPassRate(passRate);
        questionDetailInfoRes.setIsResolved(count > 0);
        return questionDetailInfoRes;
    }

    @Override
    @Transactional
    public String addQuestion(AddQuestionParam addQuestionParam) {
        Problem problem = new Problem();
        ProblemCheck problemCheck = new ProblemCheck();
        ProblemDetail problemDetail = new ProblemDetail();
        BeanUtils.copyProperties(addQuestionParam, problem);
        Long problemId = IdWorker.getId();
        problem.setId(problemId);
        problemMapper.insert(problem);
        problemCheck.setId(IdWorker.getId());
        problemCheck.setProblemId(problemId);
        problemCheck.setInput(addQuestionParam.getExampleInput());
        problemCheck.setOutput(addQuestionParam.getExampleOutput());
        problemCheckMapper.insert(problemCheck);
        BeanUtils.copyProperties(addQuestionParam, problemDetail);
        problemDetail.setId(problemId);
        problemDetailMapper.insert(problemDetail);
        return "success";
    }

    @Override
    @Transactional
    public String addTestCase(AddTestCaseParam addTestCaseParam) {
        Long problemId = addTestCaseParam.getId();
        Problem problem = problemMapper.getProblemByProblemId(problemId);
        if (problem == null) {
            return "找不到对应题目!";
        }
        ProblemCheck problemCheck = new ProblemCheck();
        BeanUtils.copyProperties(addTestCaseParam, problemCheck);
        problemCheck.setId(IdWorker.getId());
        problemCheckMapper.insert(problemCheck);
        return "success";
    }

    @Override
    public List<TestCaseInfoRes> getProblemCheckListByProblemId(Long questionId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<ProblemCheck> problemCheckList = problemCheckMapper.getProblemCheckListByProblemId(questionId);
        List<TestCaseInfoRes> resList = problemCheckList.stream().map(item -> {
            TestCaseInfoRes testCaseInfoRes = new TestCaseInfoRes();
            BeanUtils.copyProperties(item, testCaseInfoRes);
            return testCaseInfoRes;
        }).collect(Collectors.toList());
        return resList;
    }

    @Override
    @Transactional
    public String deleteProblem(Long questionId) {
        problemMapper.deleteById(questionId);
        problemDetailMapper.deleteById(questionId);
        problemCheckMapper.deleteAllByProblemId(questionId);
        submitMapper.deleteAllByProblemId(questionId);
        solutionMapper.deleteAllByProblemId(questionId);
        return "success";
    }

    @Override
    @Transactional
    public String deleteTestCaseByTestCaseId(Long testCaseId) {
        problemCheckMapper.deleteById(testCaseId);
        return "success";
    }

    @Override
    @Transactional
    public String updateQuestion(UpdateQuestionParam updateQuestionParam) {
        Problem problem = new Problem();
        ProblemDetail problemDetail = new ProblemDetail();
        BeanUtils.copyProperties(updateQuestionParam, problem);
        BeanUtils.copyProperties(updateQuestionParam, problemDetail);
        problemMapper.updateById(problem);
        problemDetailMapper.updateById(problemDetail);
        return "success";
    }

    @Override
    @Transactional
    public String updateTestcase(UpdateTestcaseParam updateTestcaseParam) {
        ProblemCheck problemCheck = new ProblemCheck();
        BeanUtils.copyProperties(updateTestcaseParam, problemCheck);
        problemCheckMapper.updateById(problemCheck);
        return "success";
    }

    @Override
    public List<SubmitInfoRes> getSubmitInfoResListByUserId(Long userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Submit> submitList;
        if (userId == 0L) {
            submitList = submitMapper.getSubmitList();
        } else {
            submitList = submitMapper.getSubmitListByUserId(userId);
        }
        List<SubmitInfoRes> resList = submitList.stream().map(item -> {
            SubmitInfoRes submitInfoRes = new SubmitInfoRes();
            BeanUtils.copyProperties(item, submitInfoRes);
            String title = problemMapper.getTitleByProblemId(item.getProblemId());
            String userName = userMapper.getUserNameByUserId(item.getUserId());
            submitInfoRes.setTitle(title);
            submitInfoRes.setUserName(userName);
            return submitInfoRes;
        }).collect(Collectors.toList());
        return resList;
    }

    @Override
    public R<SubmitInfoDetailRes> getSubmitInfoDetailResBySubmitId(Long submitId) {
        Submit submit = submitMapper.selectById(submitId);
        if (submit == null) {
            return R.error("找不到内容!");
        }
        if (BaseContext.getLevel() == 0 && !Objects.equals(BaseContext.getId(), submit.getUserId())) {
            return R.error("权限不足!");
        }
        SubmitInfoDetailRes submitInfoDetailRes = new SubmitInfoDetailRes();
        BeanUtils.copyProperties(submit, submitInfoDetailRes);
        String title = problemMapper.getTitleByProblemId(submit.getProblemId());
        String userName = userMapper.getUserNameByUserId(submit.getUserId());
        submitInfoDetailRes.setTitle(title);
        submitInfoDetailRes.setUserName(userName);
        return R.success("提交内容").data(submitInfoDetailRes);
    }


}











